<template>
    <div class="template-layout">

        <div class="detail-title">
            <span @click="goBack(-2)">Product templates</span>
            <span @click="goBack(-1)">Detail</span>
            <span>Download mockups</span>
        </div>

        <h3>Please select the mockup image(s) to download</h3>

        <!-- 加载中 -->
        <UxLoading :loading="loading" />

        <!-- 模特列表 -->
        <ul class="detail-models" v-if="detail">
            <li v-for="model in detail.model_img" :key="model.id" :class="{active:mockupSelect.indexOf(model.id) >= 0}">
                <strong v-text="model.surface_name + ':'"></strong>
                <CommonTemplatePreview :baseModel="model" :baseColor="colorBase" size="large" />
                <i @click="setMockupSelect(model)">
                    <svg-icon name="checkbox-active" />
                </i>
            </li>
        </ul>

        <!-- 选择颜色 -->
        <ul class="detail-colors" v-if="detail">
            <li v-for="color in detail.color_list" :key="color.color_id" @click="setColorSelect(color)">
                <CommonColorBlock :color="color" :active="colorSelect.indexOf(color.color_id) >= 0"></CommonColorBlock>
            </li>
        </ul>

        <!-- 下载格式 -->
        <ul class="detail-format" v-if="detail">
            <li @click="fileFormat = 'jpg'" :class="{active:fileFormat == 'jpg'}"><em>JPG</em>(Smaller file size; Store loads faster)</li>
            <li @click="fileFormat = 'png'" :class="{active:fileFormat == 'png'}"><em>PNG</em>(Bigger file size; higher-quality image)</li>
        </ul>

        <!-- 下载按钮 -->
        <div class="detail-action" v-if="detail">
            <button @click="goBack(-1)">Cancel</button>
            <button type="primary" :disabled="mockupSelect.length == 0 || colorSelect.length == 0" @click="downloadMockup()">Download mockups</button>
        </div>

        <!-- 下载进度弹窗 -->
        <UxDialog :visible="!!downloading" class="detail-downloading">
            <el-progress type="circle" color="#ea4c89" :percentage="downloading" :width="96"></el-progress>
            <p>Downloading</p>
        </UxDialog>

    </div>
</template>
<script>

import JSZip from "jszip";
import FileSaver from "file-saver";

export default {
    name: "UserTemplateMockup",
    layout: "layout-user",
    data () {
        return {
            tid: 0,
            detail: null,
            loading: true,
            downloading: 0,
            mockupSelect: [],
            colorSelect: [],
            colorBase: null,
            fileFormat: 'jpg',
        };
    },
    methods: {
        // 获取数据
        async getDetail () {
            this.loading = true;
            this.$http("storeTemplate.getTemplate", this.tid).then(response => {
                this.loading = false;
                if (response.code === 0) {
                    this.detail = response.data;
                    this.dataInit();
                    // sessionStorage.setItem('/user/template/detail', JSON.stringify({ tid: this.tid, detail: this.detail }))
                } else {
                    this.goBack(-1);
                }
            })
        },

        // 数据初始化
        dataInit () {

            this.detail.size_price = [...this.detail.size_price].sort((a, b) => a.sort - b.sort)
            this.detail.color_list = [...this.detail.color_list].sort((a, b) => a.sort - b.sort)

            // 模特默认不选
            // this.mockupSelect = this.detail.model_img.map(i => i.id);
            // 颜色默认选择前两个
            this.colorSelect = this.detail.color_list.slice(0, 2).map(i => i.color_id);
            // 基础色选第一个
            this.colorBase = this.detail.color_list[0] || null;

        },


        // 选中模特图
        setMockupSelect (model) {
            const select = [];
            this.detail.model_img.map(item => {
                const index = this.mockupSelect.indexOf(item.id);
                if (index >= 0 && item.id != model.id) {
                    // 其他的选中，过滤掉id不同的情况
                    select.push(item.id);
                } else if (index < 0 && item.id == model.id) {
                    select.push(item.id);
                }
            })
            this.mockupSelect = select;
        },

        // 选中颜色
        setColorSelect (color) {
            const select = [];
            this.detail.color_list.map(item => {
                const index = this.colorSelect.indexOf(item.color_id);
                if (index >= 0 && item.color_id != color.color_id) {
                    // 其他的选中，过滤掉color_id不同的情况
                    select.push(item.color_id);
                } else if (index < 0 && item.color_id == color.color_id) {
                    select.push(item.color_id);
                }
            })
            this.colorSelect = select;
        },

        // 返回
        goBack (step) {
            const value = Math.abs(parseInt(step)) || 0;
            if (window.history.length <= value + 1) {
                // 返回列表页
                if (value == 1) {
                    this.$router.push({ path: '/user/template/detail', query: query });
                } else {
                    this.$router.push('/user/template')
                }
            } else {
                this.$router.go(-value);
            }
        },

        // 下载
        downloadMockup () {
            const promises = [];
            const modelObj = Object.fromEntries(this.detail.model_img.map((i) => [i.id, i]));
            const colorObj = Object.fromEntries(this.detail.color_list.map((i) => [i.color_id, i]));
            const imageobj = {};

            // 进度
            const percent = {
                total: 0, // 至少有一步
                count: 0,
                timer: null,
                value: 0,
            }

            // 设置进度
            const setPercent = (init) => {

                if (!init) {
                    percent.count += 1;
                    percent.value = Math.max(1, Math.min(100, parseInt(100 * (percent.count / percent.total))));
                    this.downloading = percent.value
                } else {
                    //
                }

                let value = Math.max(1, Math.min(99, parseInt(100 * ((percent.count + 1) / percent.total))))

                if (percent.value >= value) {
                    percent.timer && clearTimeout(percent.timer);
                } else {
                    const time = parseInt(Math.random() * 1000)
                    percent.value += 1;
                    percent.timer && clearTimeout(percent.timer);
                    percent.timer = setTimeout(e => setPercent(true), time)
                    this.downloading = percent.value;
                }
            }

            // 下载图片
            const loadImage = (url) => {
                percent.total += 1;
                return new Promise((res, rej) => {
                    let count = 3;
                    const createImage = () => {

                        const img = new Image();
                        img.onload = () => {
                            imageobj[url] = img;
                            setPercent();
                            res(img);
                        };
                        img.onerror = (err) => {
                            count -= 1;
                            if (count > 0) {
                                setTimeout(createImage, 500);
                            } else {
                                // 加载多次都失败了
                                rej(err)
                            }
                        };

                        img.crossOrigin = "anonymous";
                        img.src = this.$getImageUrl(url, 'original');
                    }

                    createImage();
                })
            }

            // 生成模特图
            const makeImage = (zip, model, color, index) => {

                return new Promise(res => {
                    const modelImage = imageobj[model.model_url];
                    const surface = (model.surface_name || '').toLowerCase();
                    const name = (surface.match(/^\S+/g) || [])[0] || '';
                    const taxture = color['bg_' + name] ? imageobj[color['bg_' + name]] : null;
                    const filetype = this.fileFormat;
                    const canvas = document.createElement('canvas');
                    const ctx = canvas.getContext("2d");

                    canvas.width = modelImage.width;
                    canvas.height = modelImage.height;

                    if (taxture) {
                        // 有纹理，画底图
                        ctx.drawImage(taxture, 0, 0, taxture.width, taxture.height, 0, 0, canvas.width, canvas.height);
                    } else {
                        // 没有纹理，画底色
                        ctx.fillStyle = this.$modelBackgroundColor(color.color_num, model);
                        ctx.fillRect(0, 0, canvas.width, canvas.height);
                    }

                    // 画图
                    ctx.drawImage(modelImage, 0, 0, modelImage.width, modelImage.height, 0, 0, canvas.width, canvas.height);

                    // 推入压缩包
                    canvas.toBlob(function (blob) {
                        zip.file('Mannequin_Image' + index + '.' + filetype, blob);
                        setPercent();
                        res();
                    }, 'image/' + filetype);
                })
            }


            // 01.加载模特图片
            this.mockupSelect.map(id => {
                const model = modelObj[id] || {};
                const url = model.model_url || '';
                url && promises.push(loadImage(url))
            })
            // 02.下载颜色图片
            this.colorSelect.map(id => {
                const color = colorObj[id] || {};
                color.bg_front && promises.push(loadImage(color.bg_front))
                color.bg_back && promises.push(loadImage(color.bg_back))
            })

            // 开始下载
            // 添加生成的步骤
            percent.total += this.mockupSelect.length * this.colorSelect.length;
            percent.value = 1;
            this.downloading = percent.value;
            setPercent(true);


            // 03.生成图片
            Promise.all(promises).then(images => {
                const zip = new JSZip();
                const makes = [];
                let index = 0;

                this.mockupSelect.map(id => {
                    const model = modelObj[id] || {};
                    // 02.下载颜色图片
                    this.colorSelect.map(id => {
                        const color = colorObj[id] || {};
                        makes.push(makeImage(zip, model, color, ++index))
                    })
                });
                return Promise.all(makes).then(res => {
                    return Promise.resolve(zip.generateAsync({ type: "blob" }))
                })
            }).then(content => {
                // 05.下载
                FileSaver(content, "Mannequin_Images.zip");
                this.downloading = 0;
                this.$uxMessage.success('Successfully downloaded.')
            }).catch(error => {
                this.$uxMessage.error('Download failed. Please try again.')
                this.downloading = 0;
            })

        }
    },
    created () {
        // 缓存
        if (process.client) {
            let session = {}

            try {
                session = JSON.parse(sessionStorage.getItem('/user/template/detail') || '{}');
            } catch (e) {
                session = {};
            }

            const query = this.$route.query || {}
            const tid = parseInt(query.tid) || '';
            const change = !session.tid || session.tid != tid;

            if (change) {
                this.tid = tid;
                this.getDetail();
            } else {
                this.tid = tid;
                this.detail = session.detail;
                this.loading = false;
                this.dataInit();
            }
        }
    },
};
</script>
<style lang="scss" scoped>
.template-layout {
    position: relative;
    min-height: 100%;
    background: #fff;
    border-radius: 8px;
    z-index: 0;
    & > .loading {
        top: 41px;
    }
    & > h3 {
        padding: 26px 90px 0;
        font-size: 18px;
        font-family: Roboto-Medium, Roboto;
        font-weight: 500;
        color: #000000;
        line-height: 18px;
    }
}

.detail-title {
    display: flex;
    width: 100%;
    line-height: 40px;
    padding: 0 90px;
    font-size: 14px;
    color: #555555;
    border-bottom: 1px solid #ebebeb;
    box-sizing: border-box;
    position: sticky;
    top: 78px;
    background: #fff;
    border-radius: 8px 8px 0 0;
    z-index: 1;
    span {
        margin-left: 28px;
        position: relative;
        cursor: pointer;

        &:hover {
            color: #ea4c89;
        }
        &::before {
            content: '';
            position: absolute;
            width: 6px;
            height: 6px;
            border-top: 2px solid #555;
            border-right: 2px solid #555;
            top: 50%;
            left: -20px;
            transform: translateY(-50%) rotate(45deg);
        }

        &:first-child {
            margin-left: 0;
            &::before {
                display: none;
            }
        }

        &:last-child {
            color: #000;
            cursor: default;
            &:hover {
                color: #000;
            }
        }
    }
}

.detail-models {
    display: flex;
    margin: 0 90px;

    li {
        padding-top: 24px;
        position: relative;
        flex: 1;
        margin: 6px;
        & > strong {
            font-size: 14px;
            font-family: Roboto-Regular, Roboto;
            color: #000000;
            line-height: 20px;
            font-weight: normal;
        }

        & > i {
            position: absolute;
            left: 8px;
            top: 64px;
            width: 26px;
            height: 26px;
            background: #ffffff;
            border-radius: 3px;
            line-height: 26px;
            text-align: center;
            font-size: 12px;
            color: #666;
            user-select: none;
            cursor: pointer;

            &::before {
                content: '';
                position: absolute;
                width: 20px;
                height: 20px;
                border-radius: 2px;
                border: 2px solid #666666;
                left: 50%;
                top: 50%;
                box-sizing: border-box;
                transform: translate(-50%, -50%);
            }

            svg {
                position: absolute;
                width: 20px;
                height: 20px;
                left: 50%;
                top: 50%;
                padding: 4px;
                box-sizing: border-box;
                transform: translate(-50%, -50%);
                display: none;
                fill: #fff;
            }

            &:hover {
                display: block;
            }
        }

        &.active {
            &.active {
                i:before {
                    background: #ea4c89;
                    border-radius: 2px;
                    border-color: transparent;
                }
                svg {
                    display: block;
                }
            }
        }
    }

    .template-preview {
        margin-top: 10px;
        border: 1px solid #ddd;
        border-radius: 4px;
        overflow: hidden;
    }
}

.detail-colors {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    margin: 36px 85px 0;

    &::before {
        content: 'Please select the color(s):';
        line-height: 40px;
        width: 100%;
        box-sizing: border-box;
        font-size: 18px;
        font-family: Roboto-Medium, Roboto;
        font-weight: 500;
        color: #000000;
        line-height: 20px;
        padding: 0 5px;
        margin-bottom: 8px;
    }

    li {
        margin: 5px;
        width: 24px;
        height: 24px;
        border-radius: 2px;
        position: relative;
        cursor: pointer;
        user-select: none;
        div {
            width: 100%;
            height: 100%;
        }

        svg {
            position: absolute;
            left: 0;
            top: 0;
            width: 24px;
            height: 24px;
            padding: 6px;
            box-sizing: border-box;
            fill: #fff;
            -webkit-filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.7));
            filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.7));
            // display: none;
            opacity: 0;
        }
        &::before {
            content: '';
            position: absolute;
            left: 0;
            right: 0;
            bottom: 0;
            top: 0;
            border: 1px solid rgba(0, 0, 0, 0.2);
            border-radius: 2px;
        }

        &.active svg {
            // display: block;
            opacity: 1;
        }
    }
}
.detail-format {
    position: relative;
    margin: 36px 90px 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    padding-bottom: 100px;

    &::before {
        content: 'Format:';
        display: block;
        line-height: 40px;
        width: 100%;
        box-sizing: border-box;
        font-size: 18px;
        font-family: Roboto-Medium, Roboto;
        font-weight: 500;
        color: #000000;
        line-height: 20px;
        margin-bottom: 4px;
    }

    li {
        line-height: 18px;
        padding: 10px 30px;
        position: relative;
        font-size: 14px;
        font-family: Roboto-Regular, Roboto;
        color: #000000;
        cursor: pointer;

        em {
            font-family: Roboto-Medium, Roboto;
            font-weight: 500;
        }
        &::before {
            content: '';
            position: absolute;
            left: 0;
            top: 50%;
            transform: translateY(-50%);
            width: 16px;
            height: 16px;
            border-radius: 16px;
            border: 1px solid #919191;
        }

        &.active::before {
            border-color: #ea4c89;
        }
        &.active::after {
            content: '';
            position: absolute;
            left: 6px;
            top: 50%;
            transform: translateY(-50%);
            width: 6px;
            height: 6px;
            border-radius: 6px;
            background: #ea4c89;
        }
    }
}

.detail-action {
    left: 252px;
    bottom: 0px;
    text-align: center;
    z-index: 1;
    border-top: 1px solid #dcdcdc;
    padding: 20px 0;
    display: flex;
    justify-content: center;
    background: #fff;
    border-radius: 0 0 8px 8px;

    button {
        height: 40px;
        min-width: 160px;
        margin: 0 7px;
        padding: 0 32px;
        font-weight: bold;
    }
}

.detail-downloading {
    &::v-deep .dialog-content {
        width: 320px;
        height: 320px;
        background: #ffffff;
        border-radius: 28px;

        & > h6 {
            display: none;
        }

        .dialog-body {
            display: flex;
            flex-direction: column;
            overflow: hidden;
            justify-content: center;
            align-items: center;
        }
    }

    .el-progress {
        width: 96px;
        height: 96px;

        &::v-deep {
            .el-progress-circle {
                width: 96px;
                height: 96px;
            }

            .el-progress__text {
                font-size: 20px;
                font-family: Roboto-Medium, Roboto;
                font-weight: 500;
                color: #000000;
            }
        }
    }
    p {
        margin-top: 24px;
        font-size: 14px;
        font-family: Roboto-Regular, Roboto;
        font-weight: 400;
        color: #000000;
        line-height: 16px;
    }
}
</style>
